import os
import shutil
import subprocess

def copy_file_content(source_path, target_path, plain_text):
    """使用系统命令复制文件内容到目标文件
    
    参数:
    source_path -- 源文件路径
    target_path -- 目标文件路径
    返回:
    bool -- 复制成功返回True，失败返回False
    """
    # 检查源文件是否存在
    if not os.path.exists(source_path):
        print(f"错误: 源文件 '{source_path}' 不存在")
        return False
    
    # 检查源文件是否为文件
    if not os.path.isfile(source_path):
        print(f"错误: '{source_path}' 不是一个文件")
        return False
    
    # 确保目标目录存在
    target_dir = os.path.dirname(target_path)
    if target_dir and not os.path.exists(target_dir):
        try:
            os.makedirs(target_dir)
        except Exception as e:
            print(f"创建目标目录失败: {e}")
            return False
    
    try:
        # 处理路径中包含空格的情况
        source_path_quoted = f'{source_path}'
        target_path_quoted = f'{target_path}'

        if plain_text == True:
            # 构造命令: type 源文件 > 目标文件
            cmd = f'cat {source_path_quoted} > {target_path_quoted}'
            # 执行命令
            result = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True)
            # 检查命令执行结果
            if result.returncode != 0:
                print(f"复制失败: {result.stderr}")
                return False
        else:
            shutil.copy(source_path_quoted, target_path_quoted)
    except Exception as e:
        print(f"发生错误: {e}")
        return False
    return True

def copy_directory(src_dir, dst_dir, suffixes=None):
    # 检查源目录是否存在
    if not os.path.exists(src_dir):
        print(f"错误: 源目录 '{src_dir}' 不存在")
        return False
    
    # 检查源目录是否为目录
    if not os.path.isdir(src_dir):
        print(f"错误: '{src_dir}' 不是一个目录")
        return False
    
    # 确保目标目录存在
    if not os.path.exists(dst_dir):
        try:
            os.makedirs(dst_dir)
        except Exception as e:
            print(f"创建目标目录失败: {e}")
            return False
    
    all_success = True
    # 遍历源目录，获取所有文件和目录
    items = traverse_directory(src_dir, suffixes)
    
    # 处理每个项目
    for item in items:
        # 计算相对路径
        rel_path = os.path.relpath(item['path'], src_dir)
        # 构建目标路径
        target_path = os.path.join(dst_dir, rel_path)
        if item['type'] == 'directory':
            # 创建目录
            if not os.path.exists(target_path):
                try:
                    os.makedirs(target_path)
                except Exception as e:
                    print(f"创建目录 '{target_path}' 失败: {e}")
                    all_success = False
                    break
        elif item['type'] == 'file':
            ret = copy_file_content(item['path'], target_path, item['plain_text'])
            if ret == False:
                print('copy file fail, path:{}'.format(item['path']))
                all_success = False
                break
    return all_success

def traverse_directory(directory_path, suffixes=None):
    """遍历目录及其子目录，返回所有文件和子目录的信息列表
    每个元素是字典:
    - 目录: {'path': 路径, 'type': 'directory'}
    - 文件: {'path': 路径, 'type': 'file', 'plain_text': 布尔值，表示文件后缀是否在suffixes列表中}
    
    参数:
    directory_path -- 要遍历的目录路径
    suffixes -- 可选，文件后缀名列表，如['.txt', '.py']。只收集匹配这些后缀的文件
                如果为None或空列表，则不过滤文件
    """
    result = []
    # 检查目录是否存在
    if not os.path.exists(directory_path):
        print(f"错误: 目录 '{directory_path}' 不存在")
        return result
    
    # 检查路径是否为目录
    if not os.path.isdir(directory_path):
        print(f"错误: '{directory_path}' 不是一个目录")
        return result
    
    # 遍历目录
    for root, dirs, files in os.walk(directory_path):
        # 添加当前目录
        print('append, dir, path:{}'.format(root))
        result.append({'path': root, 'type': 'directory'})
        # 添加当前目录下的文件
        for file in files:
            file_path = os.path.join(root, file)
            # 获取文件后缀名
            _, ext = os.path.splitext(file)
            # 检查是否在suffixes列表中
            is_plain_text = ext in suffixes if suffixes else False
            # 添加文件信息，包含plain_text字段
            result.append({'path': file_path, 'type': 'file', 'plain_text': is_plain_text})
            print('append, file, plain_text:{}, path:{}'.format(is_plain_text, file_path))
    return result


if __name__ == "__main__":
    src_dir = "/root/temp/async_engine"
   # dst_dir = "/root/code/python/async_engine"
    dst_dir = "./async_engine"
    
    copy_directory(src_dir, dst_dir, ['.h', '.cpp', '.sh'])
   # traverse_directory(src_dir, ['.h', '.cpp', '.sh']);

